package lar.system.engine;

import java.io.PrintWriter;
import java.io.StringWriter;

import android.app.Activity;
import android.util.Log;
import lar.game.gamestate.*;
import lar.game.rules.Constants;
import lar.system.sound.Music;

public class GameLoop implements Runnable 
{
	private GameState state;
	private boolean terminate;
	public static final int FPS = 80;
	private Integer ticks;
	
	public static Object stateLock = new Object();
	long s,t;
	public GameLoop()
	{
		state = null;
		ticks = Integer.valueOf(0);
		terminate = false;
		s=t=0;
	}
	
	public GameState getState()
	{
		return state;
	}
	
	public synchronized void ChangeState(GameState newState)
	{
		
		UI.needRendering = true;
		state = newState;
		//Log.d("R", "state is now " + newState.getClass().getName());
	}
	
	public synchronized void onResume()
	{
		Log.d("R", "GameLoop.onResume called ");
		if(state != null) state.onResume();
		//if(state != null) ChangeState(((PauseMenu)state).getReturnState());
	}
	
	public synchronized void onPause()
	{
		Log.d("R", "GameLoop.onPause called ");// + state == null ? "null" : state.getClass().getName());
		if(state != null) state.onPause();
		if(state != null && !(state instanceof PauseMenu)) 
		{
			MainProgram.glSurfaceView.PushClearListeners();
			ChangeState(new PauseMenu(state));
		}
		
	}
	
	public synchronized void Terminate()
	{
		Music.stop();
		terminate = true;
	}
	
	public int getTicks()
	{
		//int ans = 0;
		//synchronized(ticks)
		//{
		//	ans = ticks;
		//}
		return ticks;
	}
	
	public synchronized boolean IsTerminated()
	{
		return terminate;
	}
	
	public void run() 
	{
		try 
		{
			Thread.sleep(10000);
		} 
		catch (InterruptedException e1) 
		{
			Log.d("R", "Engine start.");
		}
		state = new MainMenu();
		while(!IsTerminated())
		{
			s=System.nanoTime();
			synchronized(stateLock)
			{
				try
				{
					state.gameFrame();
					Music.endFrame();
				}catch(Exception e)
				{
					StringWriter sw = new StringWriter();
					PrintWriter pw = new PrintWriter(sw);
					e.printStackTrace(pw);
					MainProgram.MessageBox(pw.toString()); 
					e.printStackTrace();
				}
			}
			if(!MainProgram.smartRender || (MainProgram.smartRender && UI.needRendering)) 
				MainProgram.glSurfaceView.requestRender();
			
			
			
			Monitor.LT = (int)(System.nanoTime()-s)/1000000;
			//MainProgram.glSurfaceView.requestRender();
			t = (System.nanoTime()-s)/1000000;
			s = System.nanoTime();
			try 
			{
				int sleepTime = (int) (1000/FPS - t);
				Thread.sleep(sleepTime < 0 ? 1 : sleepTime); 
			} 
			catch (InterruptedException e) 
			{

			}
			Monitor.ST = (int)(System.nanoTime()-s)/1000000;
			ticks++;
			//Monitor.LOG();
		}
		
		MainProgram.gameLoop=null;
		MainProgram.gameLoopThread=null;
		MainProgram.currentActivity.finish();
		MainProgram.currentActivity=null;
	}

	public void onBack() 
	{
		MainProgram.glSurfaceView.hideKeyboard();
		if(state != null) state.onBack();
	}
	
	

}
